<template>
  <div class="device-status-container">
    <el-button type="primary" size="small" class="mar-btm-5" @click="clickCreateBtn">新增{{title}}参数</el-button>
    <el-table
      style="width: 100%"
      :data="paramMapData"
      size="medium"
      show-header border fit>
      <el-table-column prop="paramKey" label="参数key"></el-table-column>
      <el-table-column prop="paramAlias" label="参数别名"></el-table-column>
      <el-table-column prop="dataType" label="数据类型"></el-table-column>
      <el-table-column prop="storeKey" label="参数存储键"></el-table-column>
      <el-table-column prop="enumListText" label="参数可选值" width="200px">
        <template slot-scope="scope">
          <div v-for="(e, idx) in scope.row.enumList" :key="idx">
            key: <span class="font-color-primary">{{e.key || '--'}}</span>,
            alias: <span class="font-color-primary">{{e.alias || '--'}}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="ctrlType" label="控制方式"></el-table-column>
      <el-table-column prop="remarks" label="备注"></el-table-column>
      <el-table-column label="操作" width="180px" fixed="right">
        <template slot-scope="scope">
          <el-button
            type="text" size="medium" class="font-color-primary"
            @click="paramKeyOpt('edit', scope.$index)">编辑
          </el-button>
          <el-button
            type="text" size="medium" class="font-color-primary"
            @click="paramKeyOpt('copy', scope.$index)">复制
          </el-button>
          <el-button
            type="text" size="medium" class="font-color-danger"
            @click="paramKeyOpt('delete', scope.$index)">删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog
      :title="`${!isEditParamMap ? '新增' : '编辑'}${title}参数`"
      :visible.sync="showParamMapDialog"
      :close-on-click-modal="false"
      width="800px"
      append-to-body
      center>
      <el-form
        v-loading="paramMapFormLoading"
        :ref="paramMapFormRef"
        :model="paramMapForm"
        :rules="paramMapFormRules"
        size="small"
        label-width="100px">
        <el-form-item label="参数key" prop="paramKey">
          <el-select v-model="paramMapForm.paramKey" @change="paramKeyChanged"
                     filterable clearable class="width-100" placeholder="请选择参数key">
            <el-option-group
              v-for="(group, idx) in paramKeyData"
              :key="idx"
              :label="group.label">
              <el-option
                v-for="(item, idx) in group.options"
                :key="idx"
                :label="item.name"
                :value="item.name">
                <span>{{item.name}}</span>
                <span class="mar-lft font-color-warning">{{item.alias || ''}}</span>
              </el-option>
            </el-option-group>
          </el-select>
        </el-form-item>
        <el-form-item label="参数别名" prop="paramAlias">
          <el-input v-model="paramMapForm.paramAlias" placeholder="请填写参数别名"></el-input>
        </el-form-item>
        <el-form-item label="参数存储键">
          <el-select v-model="paramMapForm.storeKey" @change="storeKeyChanged"
                     clearable filterable class="width-100" placeholder="请选择参数存储键">
            <el-option-group
              v-for="(group, idx) in storeKeyData"
              :key="idx"
              :label="group.label">
              <el-option
                v-for="(item, idx) in group.options"
                :key="idx"
                :label="item.name"
                :value="item.name">
                <span>{{item.name}}</span>
                <span class="mar-lft font-color-warning">{{item.alias || ''}}</span>
              </el-option>
            </el-option-group>
          </el-select>
        </el-form-item>
        <el-form-item label="数据类型" prop="dataType">
          <el-radio-group v-model="paramMapForm.dataType">
            <el-radio :label="type.value" :key="idx"
                      v-for="(type, idx) in commonConfig.dataType">{{type.label}}
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="控制方式" prop="ctrlType">
          <el-radio-group v-model="paramMapForm.ctrlType">
            <el-radio :label="type.value" :key="idx"
                      v-for="(type, idx) in commonConfig.ctrlType">{{type.label}}
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="参数可选值">
          <el-button type="primary" size="mini" class="mar-btm-5" @click="addEnum">新增可选值</el-button>
          <el-table
            style="width: 100%"
            :data="enumList"
            size="medium"
            border>
            <el-table-column prop="key" label="枚举key">
              <template slot-scope="scope">
                <el-input v-model="scope.row.key" size="mini" placeholder="请填写枚举key"></el-input>
              </template>
            </el-table-column>
            <el-table-column prop="alias" label="枚举别名">
              <template slot-scope="scope">
                <el-input v-model="scope.row.alias" size="mini" placeholder="请填写枚举别名"></el-input>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="100px">
              <template slot-scope="scope">
                <a
                  class="font-weight-bold font-color-primary cursor-pointer"
                  @click="copyParamMap(scope.$index)">复制</a>
                <a
                  class="table-opt-btn font-color-danger font-weight-bold cursor-pointer mar-lft"
                  @click="deleteEnum(scope.$index)">删除</a>
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
        <el-form-item label="备注">
          <el-input type="textarea" v-model="paramMapForm.remarks" placeholder="请填写备注"></el-input>
        </el-form-item>
        <div class="text-align-right">
          <el-form-item>
            <el-button size="medium" @click="paramMapFormCanceled">取消</el-button>
            <el-button size="medium" type="primary" @click="paramMapFormSubmitted">保存</el-button>
          </el-form-item>
        </div>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
  import {commonConfig} from "@/config/common";
  import {tableOptBtnConfig} from '@/config/table';
  import {confirmHandle, deepCopyWithJson} from "@/utils";

  export default {
    name: "GenCommParams",
    props: {
      title: {
        default: ''
      },
      type: {
        default: ''
      },
      deviceType: {
        default: ''
      },
      paramMapData: {
        default: () => {
          return []
        }
      },
    },
    data() {
      return {
        commonConfig: commonConfig,
        paramKeyData: [], // paramKey 可选值
        storeKeyData: [], // storeKey 可选值
        selectedIdx: -1, // 标志当前选中的paramMap
        showParamMapDialog: false,
        paramMapFormLoading: false,
        paramMapForm: {},
        paramMapFormRules: {},
        paramMapFormRef: 'paramMapFormRef',
        isEditParamMap: false,
        enumList: [],
      }
    },
    watch: {
      deviceType() {
        this.getGenParamData();
      },
    },
    created() {
      this.initParamMapForm();
    },
    methods: {
      // 参数设置相关
      initParamMapForm() {
        const commonRules = {
          paramKey: [
            {required: true, message: '请填写参数key', trigger: 'change'}
          ],
          paramAlias: [
            {required: true, message: '请填写参数别名', trigger: 'change'}
          ],
          dataType: [
            {required: true, message: '请选择数据类型', trigger: 'change'}
          ],
        };
        switch (this.type) {
          case 'resp':
            this.paramMapFormRules = commonRules;
            break;
          case 'req':
            this.paramMapFormRules = {
              ...commonRules,
              ctrlType: [{required: true, message: '请选择控制方式', trigger: 'change'}]
            };
            break;
          default:
            break;
        }
        this.paramMapForm = {
          paramKey: '',
          paramValue: '',
          paramAlias: '',
          storeKey: '',
          storeKeyAlias: '',
          dataType: commonConfig.dataType[0].value,
          ctrlType: commonConfig.ctrlType[0].value,
          remarks: ''
        };
        this.enumList = [];
      },
      resetParamMapForm() {
        this.initParamMapForm();
        const paramMapForm = this.$refs[this.paramMapFormRef];
        paramMapForm && paramMapForm.resetFields();
      },
      clickCreateBtn() {
        this.isEditParamMap && this.resetParamMapForm();
        this.showParamMapDialog = true;
        this.isEditParamMap = false;
      },
      paramKeyOpt(type, idx) {
        this.selectedIdx = idx
        const paramMap = deepCopyWithJson(this.paramMapData[idx]);
        switch (type) {
          case tableOptBtnConfig.edit.type:
            this.showParamMapDialog = true;
            this.isEditParamMap = true;
            this.paramMapForm = paramMap;
            this.enumList = paramMap.enumList;
            break;
          case tableOptBtnConfig.copy.type:
            this.showParamMapDialog = true;
            this.isEditParamMap = false;
            this.paramMapForm = paramMap;
            this.enumList = paramMap.enumList;
            delete this.paramMapForm['_id'];
            break;
          case tableOptBtnConfig.delete.type:
            this.deleteGenCommParam(paramMap);
            break;
          default:
            break;
        }
      },
      paramKeyChanged() {
        let flatParamKeyData = [];
        this.paramKeyData.forEach(gf => {
          flatParamKeyData = _.union(flatParamKeyData, gf.options || [])
        });
        const paramKey = flatParamKeyData.find(pk => {
          return pk.name === this.paramMapForm.paramKey
        }) || {};
        this.paramMapForm.paramAlias = paramKey.alias || '';
      },
      storeKeyChanged() {
        let destStoreKey = {};
        for (let i = 0; i < this.storeKeyData.length; i++) {
          const sk = this.storeKeyData[i];
          const {options = []} = sk;
          const storeKey = options.find(sk => {
            return sk.name === this.paramMapForm.storeKey
          });
          if (storeKey) {
            destStoreKey = storeKey;
            break;
          }
        }
        this.paramMapForm.storeKeyAlias = destStoreKey.alias || '';
      },
      getGenParamData() {
        const param = {deviceType: {$in: [this.deviceType, '00']}};
        API.genParam.genParamAll(param).then(result => {
          const {data = []} = result;
          this.paramKeyData = [];
          this.storeKeyData = [];
          const initParamKeyData = [
            {
              label: '通用',
              options: []
            },
            {
              label: '常规参数',
              options: []
            },
            {
              label: '数组类参数',
              options: []
            },
          ];
          const initStoreKeyData = [
            {
              label: '通用',
              options: []
            },
            {
              label: '设备特有',
              options: []
            },
          ];
          data.forEach(d => {
            if (d.deviceType === '00') {
              switch (d.type) {
                case commonConfig.genParamType[0].value:
                  initParamKeyData[0].options.push(d);
                  break;
                case commonConfig.genParamType[1].value:
                  initParamKeyData[1].options.push(d);
                  break;
                case commonConfig.genParamType[2].value:
                  initStoreKeyData[0].options.push(d);
                  break;
                default:
                  break;
              }
            } else {
              switch (d.type) {
                case commonConfig.genParamType[0].value:
                  initParamKeyData[1].options.push(d);
                  break;
                case commonConfig.genParamType[1].value:
                  initParamKeyData[2].options.push(d);
                  break;
                case commonConfig.genParamType[2].value:
                  initStoreKeyData[1].options.push(d);
                  break;
                default:
                  break;
              }
            }
          });
          initParamKeyData.forEach(pk => {
            const {options = []} = pk;
            options.length && (this.paramKeyData.push(pk));
          });
          initStoreKeyData.forEach(pk => {
            const {options = []} = pk;
            options.length && (this.storeKeyData.push(pk));
          });
        }).catch(err => {
          console.log('err', err)
        });
      },
      deleteGenCommParam(paramMap = {}) {
        const {paramAlias, paramKey} = paramMap;
        const confirmLabel = `确定要删除${this.title}参数：${paramAlias || paramKey} 吗?`;
        confirmHandle({label: confirmLabel}).then(() => {
          this.paramMapData.splice(this.selectedIdx, 1);
          this.resetParamMapForm();
        }).catch(() => {
        });
      },
      paramMapFormCanceled() {
        this.showParamMapDialog = false;
      },
      paramMapFormSubmitted() {
        this.$refs[this.paramMapFormRef].validate((valid) => {
          if (!valid) return;
          this.paramMapFormLoading = true;
          const params = {
            ...this.paramMapForm,
            enumList: this.enumList
          };
          if (!this.isEditParamMap) {
            this.paramMapData.push(params);
            this.resetParamMapForm();
          } else {
            console.log("编辑", this.paramMapData)
            this.paramMapData.splice(this.selectedIdx, 1, params)
          }
          this.paramMapFormLoading = false;
          this.showParamMapDialog = false;
        });
      },

      // 参数可选值相关
      addEnum() {
        this.enumList.push({
          key: '',
          value: '',
          alias: '',
        })
      },
      copyParamMap(idx) {
        const src = deepCopyWithJson(this.enumList[idx]);
        this.enumList.splice(idx, 0, src);
      },
      deleteEnum(idx) {
        const enumInfo = this.enumList[idx];
        confirmHandle({label: `确定要删除参数可选值：${enumInfo.key} 吗?`}).then(() => {
          this.enumList.splice(idx, 1);
        }).catch(() => {
        });
      },
    },
  }
</script>

<style scoped>

</style>
